#include "textflag.h"
// ----函数语法---
// 函数标识符通过TEXT汇编指令定义，表示该行开始的指令定义在TEXT内存段
// 函数的定义的语法

// TEXT symbol(SB), [flags,] $framesize[-argsize] // TEXT指令、函数名、可选的flags标志、函数帧大小和可选的函数参数大小

// 两种定义方式
// 第一种是最完整的写法：函数名部分包含了当前包的路径，同时指明了函数的参数大小为32个字节（对应参数和返回值的4个int类型）。
// 第二种写法则比较简洁，省略了当前包的路径和参数的大小。如果有NOSPLIT标注，会禁止汇编器为汇编函数插入栈分裂的代码
// TEXT ·Swap(SB),NOSPLIT,$0-32 // func Swap(a, b int) (int, int)

// TEXT ·Swap(SB),NOSPLIT,$0 // func Swap(a, b int) (int, int)


// ---- 函数参数和返回值---
// 从代码可以看出a、b、ret0和ret1的内存地址是依次递增的，FP伪寄存器是第一个变量的开始地址。
// `MOVQ` 是汇编语言中的一条指令，它用于移动（即复制）64位（8字节）的数据。
// 例如，在你提供的代码中，`MOVEQ a+0(FP), AX` 这条指令会将内存地址 `a+0(FP)` 的64位值复制到 `AX` 寄存器中。
TEXT ·Swap(SB),NOSPLIT,$0-32
    MOVQ a+0(FP),AX // AX = a
    MOVQ b+8(FP),BX // BX = b
    MOVQ BX,ret0+16(FP) // ret0 = BX
    MOVQ AX,ret1+24(FP) // ret1 = AX
    RET

// ---- 参数和返回值的内存布局 ----
// 参数和返回值需要对齐对自身大小的整数倍；
// 如：a是bool类型，大小1字节，b是int16类型，大小2字节，虽然a和b相邻，但是b大小是2字节，所以a和b直接需要有1个字节空洞
// c是int64类型，大小8字节，所以b和c直接需要有4字节空洞；
// 这样做的原因：
// 内存对齐的主要目的是为了提高内存访问的效率。许多计算机处理器在访问对齐的数据时会更有效率，因为它们的内存子系统是以固定大小的块来操作的。
// 如果数据没有对齐，处理器可能需要进行额外的内存访问操作才能获取完整的数据。
TEXT ·Foo(SB),NOSPLIT,$0-32
    MOVQ a+0(FP), AX
    MOVQ b+2(FP), BX
    MOVQ c_dat+8*1(FP), CX
    MOVQ c_len+8*2(FP), DX
    MOVQ c_cap+8*3(FP), DI
    RET
